package com.heima.scan.service.impl;

import cn.hutool.dfa.SensitiveUtil;
import com.alibaba.fastjson.JSON;
import com.heima.aliyun.AliyunGreenTemplate;
import com.heima.apis.article.ArticleClient;
import com.heima.apis.dto.ArticleDto;
import com.heima.file.MinIOTemplate;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.wemedia.entity.WmChannel;
import com.heima.model.common.wemedia.entity.WmNews;
import com.heima.model.common.wemedia.entity.WmUser;
import com.heima.scan.dao.WmChannelDao;
import com.heima.scan.dao.WmNewsDao;
import com.heima.scan.dao.WmSensitiveDao;
import com.heima.scan.dao.WmUserDao;
import com.heima.scan.service.WmNewsAutoScanService;
import com.heima.utils.common.SensitiveWordUtil;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {
    @Resource
    private WmNewsDao wmNewsDao;
    @Resource
    private AliyunGreenTemplate aliyunGreenTemplate;
    @Resource
    private MinIOTemplate minIOTemplate;
    @Resource
    private WmSensitiveDao wmSensitiveDao;
    @Resource
    private WmUserDao wmUserDao;
    @Resource
    private WmChannelDao wmChannelDao;
    @Resource
    private ArticleClient articleClient;

    @Override
    public void autoScanNews(Long newsId) {
        WmNews wmNews = wmNewsDao.queryById(newsId);
        if (wmNews == null) {
            return;
        }
        if (wmNews.getStatus() != 1) {
            return;
        }
        //提取图片和文字信息
        Map<String, Object> textAndImages = extractTextAndImages(wmNews);
        String text = (String) textAndImages.get("text");
        List<String> images = (List<String>) textAndImages.get("images");

        //审核敏感词,可减少不必要的阿里云审核
        boolean sensitiveScan = handleSensitiveScan(wmNews, text);
        if (!sensitiveScan) {
            return;
        }

        //阿里云审核文本
        boolean textScan = handleTextScan(wmNews, text);
        if (!textScan) {
            return;
        }
        //阿里云审核图片
        boolean imageScan = handleImageScan(wmNews, images);
        if (!imageScan) {
            return;
        }

        //审核成功,准备发布新闻,如果未到发布时间则改状态为8,待发布状态,结束任务
        if (wmNews.getPublishTime().getTime() >= System.currentTimeMillis()) {

            wmNews.setStatus(8);
            wmNews.setReason("审核通过,待发布!");
            wmNewsDao.update(wmNews);
            return;

        }
        //到发布时间,发布文章
        saveArticle(wmNews);
    }

    public ResponseResult saveArticle(WmNews wmNews) {

        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);
        // 手动封装 不能映射的属性,authorId,layout,authorName,channelName
        articleDto.setNewsId(wmNews.getId());
        articleDto.setAuthorId(wmNews.getUserId());
        articleDto.setLayout(wmNews.getType());
        WmUser wmUser = wmUserDao.queryById(Integer.parseInt(wmNews.getUserId().toString()));
        if (wmUser != null) {
            articleDto.setAuthorName(wmUser.getNickname());
        }
        WmChannel wmChannel = wmChannelDao.queryById(wmNews.getChannelId());
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }

        //feign远程调用,发布文章,保存到文章数据表
        ResponseResult result = articleClient.save(articleDto);
        if (result.getCode() == 200) {
            wmNews.setStatus(9);
            wmNews.setReason("发布成功！");
            wmNewsDao.update(wmNews);
        }
        return result;
    }

    private boolean handleSensitiveScan(WmNews wmNews, String text) {

        if (StringUtils.isBlank(text)) {
            return true;
        }

        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (map.size() > 0) {
            wmNews.setStatus(2);
            wmNews.setReason("文章含有敏感词!" + map);

            wmNewsDao.update(wmNews);
            return false;
        }
        return true;
    }

    private Map<String, Object> extractTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();
        HashMap<String, Object> hashmap = new HashMap<>();
        List<Map> maps = JSON.parseArray(content, Map.class);
        StringBuilder text = new StringBuilder();
        for (Map map : maps) {
            if ("text".equals(map.get("type"))) {
                text.append(map.get("value") + ",");
            }
        }
        String title = wmNews.getTitle();
        text.append(title);
        String text1 = text.toString();

        List<String> images = maps.stream()
                .filter(map -> "image".equals(map.get("type")))
                .map(map -> map.get("value").toString())
                .collect(Collectors.toList());

        String image = wmNews.getImages();
        if (StringUtils.isNotBlank(image)) {
            String[] split = image.split(",");
            images.addAll(Arrays.asList(split));
        }
        hashmap.put("text", text1);
        hashmap.put("images", images);

        return hashmap;
    }

    private boolean handleImageScan(WmNews wmNews, List<String> images) {
        if (images.size() == 0) {
            return true;
        }
        List<byte[]> bytes = images.stream().map(map -> minIOTemplate.downLoadFile(map)).collect(Collectors.toList());
        Map<String, String> imageScan = aliyunGreenTemplate.greenImageScan(bytes);

        if ("block".equals(imageScan.get("suggestion"))) {
            wmNews.setStatus(2);
            wmNews.setReason("图片审核失败!");
            wmNewsDao.update(wmNews);
            return false;
        }
        if ("review".equals(imageScan.get("suggestion"))) {
            wmNews.setStatus(3);
            wmNews.setReason("需要人工审核!");
            wmNewsDao.update(wmNews);

            return false;
        }
        return true;
    }

    private boolean handleTextScan(WmNews wmNews, String text) {
        if (StringUtils.isBlank(text)) {
            return true;
        }
        try {
        Map<String, String> textScan = aliyunGreenTemplate.greenTextScan(text);

            if ("block".equals(textScan.get("suggestion"))) {
                wmNews.setStatus(2);
                wmNews.setReason("文字审核失败!");
                wmNewsDao.update(wmNews);
                return false;
            }
            if ("review".equals(textScan.get("suggestion"))) {
                wmNews.setStatus(3);
                wmNews.setReason("需要人工审核!");
                wmNewsDao.update(wmNews);

                return false;
            }

                return true;
        }
        catch (Exception e) {
            e.printStackTrace();
            wmNews.setStatus(3);
            wmNews.setReason("阿里云审核失败!");
            wmNewsDao.update(wmNews);
            return false;
        }

    }
}
